package com.t3rik.mes.emp.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.t3rik.common.utils.DateUtils;
import com.t3rik.mes.emp.domain.EmpPieceSalaryDetails;
import com.t3rik.mes.emp.domain.EmpSalary;
import com.t3rik.mes.emp.domain.vo.EmpPieceSalaryDetailsVo;
import com.t3rik.mes.emp.mapper.EmpSalaryMapper;
import com.t3rik.mes.pro.domain.ProFeedback;
import com.t3rik.mes.pro.domain.ProProcess;
import com.t3rik.mes.pro.domain.ProTask;
import com.t3rik.mes.pro.service.IProProcessService;
import com.t3rik.mes.pro.service.IProTaskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.t3rik.mes.emp.mapper.EmpPieceSalaryDetailsMapper;

import com.t3rik.mes.emp.service.IEmpPieceSalaryDetailsService;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 员工计件工资详情Service业务层处理
 *
 * @author ykh
 * @date 2025-02-19
 */
@Service
@Slf4j
public class EmpPieceSalaryDetailsServiceImpl  extends ServiceImpl<EmpPieceSalaryDetailsMapper, EmpPieceSalaryDetails>  implements IEmpPieceSalaryDetailsService
{
    @Autowired
    private EmpPieceSalaryDetailsMapper empPieceSalaryDetailsMapper;
    @Autowired
    private EmpSalaryMapper empSalaryMapper;
    @Autowired
    private IProProcessService proProcessService;

    @Autowired
    private IProTaskService proTaskService;

    /**
     * 初始化薪资记录
     */
    @Override
    @Transactional
    public void createEmpSalaryDetail(ProFeedback feedback) {
        //获取当前时间
        Date now = DateUtils.getNowDate();
        EmpPieceSalaryDetails empPieceSalaryDetail = new EmpPieceSalaryDetails();
        //报工人id
        empPieceSalaryDetail.setUserId(feedback.getUserId());
        //用户名称
        empPieceSalaryDetail.setUserName(feedback.getUserName());
        //报工记录id
        empPieceSalaryDetail.setFeedbackId(feedback.getRecordId());
        //工序ID
        empPieceSalaryDetail.setProcessId(feedback.getProcessId());
        //任务ID
        empPieceSalaryDetail.setTaskId(feedback.getTaskId());
        //合格品数量
        empPieceSalaryDetail.setFeedbackCount(feedback.getQuantityQualified());
        empPieceSalaryDetail.setCreateTime(now);
        empPieceSalaryDetail.setUpdateTime(now);
        save(empPieceSalaryDetail);
        saveEmpSalary(feedback);

    }

    /**
     * 保存员工工资记录到总表
     */
    private void saveEmpSalary(ProFeedback feedback) {
        //判断该年度员工id在当年度是否已存在，未存在则插入一条
        LocalDateTime year = LocalDateTime.now();
        EmpSalary empSalary = empSalaryMapper.selectByUserId(feedback.getUserId(), year);
        if(empSalary==null){
            //薪资总表也插入一条数据
            EmpSalary insert = new EmpSalary();
            //获取当前年份
            insert.setYear(year.toString());
            insert.setUserId(feedback.getUserId());
            insert.setUserName(feedback.getUserName());
            empSalaryMapper.insert(insert);
            log.info("报工审批通过记录薪资详情成功");
        }
    }

//    /**
//     *   计算员工工资
//     *      计算规则：
//     *      计件工资（不含奖励）=工序单价*任务完成数
//     *      计件工资（含奖励）= 工序单价*任务完成数*奖励系数
//     * @param records
//     */
//    @Override
//    public List<EmpPieceSalaryDetailsVo> computeEmpSalary(List<EmpPieceSalaryDetails> records) {
//        List<EmpPieceSalaryDetailsVo> res = new ArrayList<>();
//        records.forEach(item->{
//            EmpPieceSalaryDetailsVo resVo = new EmpPieceSalaryDetailsVo();
//            BeanUtils.copyProperties(item, resVo);
//            Long processId = item.getProcessId();
//            ProProcess proProcess = proProcessService.selectProProcessByProcessId(processId);
//            if(proProcess != null){
//                BigDecimal price = proProcess.getPrice();
//                BigDecimal percent = proProcess.getPercent();
//                resVo.setPrice(price);
//                resVo.setPercent(percent);
//                //计件工资（不含奖励）=工序单价*任务完成数
//                BigDecimal countPrice = price.multiply(item.getFeedbackCount());
//                resVo.setCountPrice(countPrice);
//                //计件工资（含奖励）= 工序单价*任务完成数*奖励系数
//                resVo.setTotalPrice(countPrice.multiply(percent));
//                //获取工序名称
//                resVo.setProcessName(proProcess.getProcessName());
//            }
//            //获取任务名称
//            ProTask proTask = proTaskService.selectProTaskByTaskId(item.getTaskId());
//            if(proTask != null){
//                resVo.setTaskName(proTask.getTaskName());
//            }
//            res.add(resVo);
//        });
//        return res;
//    }

    @Override
    public List<EmpPieceSalaryDetailsVo> computeEmpSalary(List<EmpPieceSalaryDetails> records) {
        List<EmpPieceSalaryDetailsVo> res = new ArrayList<>();

        // 收集所有需要查询的 processId 和 taskId
        Set<Long> processIds = new HashSet<>();
        Set<Long> taskIds = new HashSet<>();
        for (EmpPieceSalaryDetails item : records) {
            processIds.add(item.getProcessId());
            taskIds.add(item.getTaskId());
        }
        if(processIds.isEmpty() || taskIds.isEmpty()){
            return res;
        }
        // 批量查询 ProProcess 和 ProTask
        List<ProProcess> proProcesses = proProcessService.selectProProcessByIds(new ArrayList<>(processIds));
        List<ProTask> proTasks = proTaskService.selectProTaskByTaskIds(new ArrayList<>(taskIds));

        // 将查询结果存储在 Map 中，方便快速查找
        Map<Long, ProProcess> processMap = new HashMap<>();
        for (ProProcess proProcess : proProcesses) {
            processMap.put(proProcess.getProcessId(), proProcess);
        }
        Map<Long, ProTask> taskMap = new HashMap<>();
        for (ProTask proTask : proTasks) {
            taskMap.put(proTask.getTaskId(), proTask);
        }

        // 计算工资
        for (EmpPieceSalaryDetails item : records) {
            EmpPieceSalaryDetailsVo resVo = new EmpPieceSalaryDetailsVo();
            BeanUtils.copyProperties(item, resVo);

            ProProcess proProcess = processMap.get(item.getProcessId());
            if (proProcess != null) {
                BigDecimal price = proProcess.getPrice();
                BigDecimal percent = proProcess.getPercent();
                resVo.setPrice(price);
                resVo.setPercent(percent);
                // 计件工资（不含奖励）=工序单价*任务完成数
                BigDecimal countPrice = price.multiply(item.getFeedbackCount());
                resVo.setCountPrice(countPrice);
                // 计件工资（含奖励）= 工序单价*任务完成数*奖励系数
                resVo.setTotalPrice(countPrice.multiply(percent));
                // 获取工序名称
                resVo.setProcessName(proProcess.getProcessName());
                //同步更新薪资详情表对应字段
                item.setPrice(price);
                item.setPercent(percent);
                item.setCountPrice(countPrice);
                item.setTotalPrice(countPrice.multiply(percent));
            }
            ProTask proTask = taskMap.get(item.getTaskId());
            if (proTask != null) {
                resVo.setTaskName(proTask.getTaskName());
            }
            res.add(resVo);
        }
        //批量更新薪资详情表，记录在records中
        // 获取代理对象
        EmpPieceSalaryDetailsServiceImpl proxy = (EmpPieceSalaryDetailsServiceImpl) AopContext.currentProxy();
        // 通过代理对象调用方法，触发事务
        proxy.updateBatchById(records);
        return res;
    }

    /**
     * 根据用户ID获取用户的工资记录
     * @param startTime
     * @return endTime
     */
    @Override
    public List<EmpPieceSalaryDetails> getListByYear(LocalDate startTime, LocalDate endTime) {
        // 查询用户工资记录
        return empPieceSalaryDetailsMapper.getListByYear(startTime, endTime);
    }
}
